package com.heatingcharge.service.unit.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.heatingcharge.common.exception.BaseException;
import com.heatingcharge.common.util.BeanValidator;
import com.heatingcharge.common.util.LevelUtil;
import com.heatingcharge.common.util.ResponseCodeEnum;
import com.heatingcharge.dto.HeatCompanyDTO;
import com.heatingcharge.entity.unit.HeatCompany;
import com.heatingcharge.mapper.unit.HeatCompanyMapper;
import com.heatingcharge.param.HeatCompanyParam;
import com.heatingcharge.service.unit.IHeatCompanyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 热力公司  服务实现类
 * </p>
 *
 * @author devin.jiang
 * @since 2019-07-12
 */
@Service
public class HeatCompanyServiceImpl extends ServiceImpl<HeatCompanyMapper, HeatCompany> implements IHeatCompanyService {

    @Override
    public List<HeatCompanyDTO> getHeatCopany() {
        List<HeatCompany> heatComponies = baseMapper.selectHeatCompany();
        List<HeatCompanyDTO> dtoList= Lists.newArrayList();
        for (HeatCompany company:heatComponies){
            HeatCompanyDTO dto= HeatCompanyDTO.adapt(company);
            dtoList.add(dto);
        }
        return dtoListToTree(dtoList);
    }

    /**
     * 新增
     * @param heatCompanyParam
     * @return
     */
    @Override
    public boolean save(HeatCompanyParam heatCompanyParam) {
        //校验字段合法性
        BeanValidator.check(heatCompanyParam);
        //检验热力公司是否已经存在
        if (checkExist(heatCompanyParam.getParentId(),heatCompanyParam.getName(),null)){
            //热力公司已经存在
            throw new BaseException(ResponseCodeEnum.HEATCOMPONY_EXIST.getMessage(),ResponseCodeEnum.HEATCOMPONY_EXIST.getCode());
        }

        HeatCompany heatCompany=HeatCompany.builder()
                .name(heatCompanyParam.getName())
                .parentId(heatCompanyParam.getParentId())
                .addr(heatCompanyParam.getAddr())
                .build();
        heatCompany.setLevel(LevelUtil.calculateLevel(getLevel(heatCompanyParam.getParentId()),heatCompanyParam.getParentId()));
        return baseMapper.insert(heatCompany)>0;
    }

    private String getLevel(Integer parentId) {
        HeatCompany heatCompany = this.getById(parentId);
        if (heatCompany == null) {
            return null;
        }
        return heatCompany.getLevel();
    }

    private boolean checkExist(Integer parentId,String companyName,Integer id) {
        QueryWrapper<HeatCompany> queryWrapper=new QueryWrapper<>();
        if (parentId!=null) {
            queryWrapper.eq("parent_id",parentId);
        }
        queryWrapper.eq("name",companyName);
        if (id!=null){
            queryWrapper.ne("id",id);
        }
        return this.list(queryWrapper).size()>0;
    }

    /**
     * 修改
     * @param heatCompanyParam
     * @return
     */
    @Override
    public boolean update(HeatCompanyParam heatCompanyParam) {
        //校验字段合法性
        BeanValidator.check(heatCompanyParam);
        //检验热力公司是否已经存在
        if (checkExist(heatCompanyParam.getParentId(),heatCompanyParam.getName(),heatCompanyParam.getId())){
            //热力公司已经存在
            throw new BaseException(ResponseCodeEnum.HEATCOMPONY_EXIST.getMessage(),ResponseCodeEnum.HEATCOMPONY_EXIST.getCode());
        }
        HeatCompany before=this.getById(heatCompanyParam.getId());
        if (ObjectUtil.isNull(before)){
            throw new BaseException(ResponseCodeEnum.HEATCOMPONY_NON_EXIST.getMessage(),ResponseCodeEnum.HEATCOMPONY_NON_EXIST.getCode());
        }
        HeatCompany after=new HeatCompany();
        BeanUtils.copyProperties(heatCompanyParam, after);

        after.setLevel(LevelUtil.calculateLevel(getLevel(heatCompanyParam.getParentId()),heatCompanyParam.getParentId()));
        return baseMapper.updateById(after)>0;
    }

    @Override
    public boolean removeById(Serializable id) {
        // 热力公司层级删除
        List<Integer> idList = this.list(Wrappers.<HeatCompany>query().lambda().eq(HeatCompany::getParentId, id)).stream().map(HeatCompany::getId).collect(Collectors.toList());
        //如果存在子热力公司  则不能删除
        if (idList.size()>0){
            throw new BaseException(ResponseCodeEnum.HEATCOMPONY_HAS_CHILDREN.getMessage(),ResponseCodeEnum.HEATCOMPONY_HAS_CHILDREN.getCode());
        }
        return super.removeById(id);
    }

    private List<HeatCompanyDTO> dtoListToTree(List<HeatCompanyDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)){
            return Lists.newArrayList();
        }
        Multimap<String,HeatCompanyDTO> levelDeptMap= ArrayListMultimap.create();
        List<HeatCompanyDTO> rootList=Lists.newArrayList();
        for (HeatCompanyDTO dto:dtoList){
            levelDeptMap.put(dto.getLevel(),dto);
            if (LevelUtil.ROOT.equals(dto.getLevel())){
                rootList.add(dto);
            }
        }
        // 按照seq从小到大排序
//        Collections.sort(rootList, new Comparator<DeptLevelDTO>() {
//            public int compare(DeptLevelDTO o1, DeptLevelDTO o2) {
//                return o1.getSeq() - o2.getSeq();
//            }
//        });
        // 递归生成树
        transformDeptTree(rootList, LevelUtil.ROOT, levelDeptMap);
        return rootList;
    }

    /**
     * 递归热力公司树
     * @param deptLevelList
     * @param level
     * @param levelDeptMap
     */
    private void transformDeptTree(List<HeatCompanyDTO> deptLevelList, String level, Multimap<String, HeatCompanyDTO> levelDeptMap) {
        for (int i = 0; i < deptLevelList.size(); i++) {
            // 遍历该层的每个元素
            HeatCompanyDTO levelDto = deptLevelList.get(i);
            // 处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level, levelDto.getId());
            // 处理下一层
            List<HeatCompanyDTO> tempList = (List<HeatCompanyDTO>) levelDeptMap.get(nextLevel);
            if (CollectionUtils.isNotEmpty(tempList)) {
                // 排序
//                Collections.sort(tempList, deptSeqComparator);
                // 设置下一层热力公司
                levelDto.setChildren(tempList);
                // 进入到下一层处理
                transformDeptTree(tempList, nextLevel, levelDeptMap);
            }
        }
    }

}
